﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Web;

namespace sqlsearcher
{
    public class LogWrite
    {
        private static object locker = new object();    //  用于锁定创建日志实例
        private static LogWrite onlyLog = null;     //  用于存储唯一日志实例
        private string logFolderName = null;    //  用于定期清理日志时需要的文件夹名称

        /// <summary>
        /// 【待设置字段】清理之前n秒的日志，单位：秒
        /// </summary>
        public static int ClearSeconds = 60 * 60 * 24 * 7;//    默认清理7天前日志

        /// <summary>
        /// 【待设置字段】日志文件存放根目录地址，格式如：E:\Web
        /// </summary>
        public static string RootLogPath = AppDomain.CurrentDomain.BaseDirectory;
        /// <summary>
        /// 【待设置字段】日志文件地址
        /// </summary>
        public static string LogFilePath;
        private LogWrite()
        {

        }
        /// <summary>
        /// 返回日志实例
        /// </summary>
        /// <returns></returns>
        public static LogWrite GetInstance(string logFolderName = "logs\\user")
        {
            lock (locker)
            {
                LogFilePath = RootLogPath + "\\" + logFolderName + "\\" + DateTime.Now.ToString("yyyy-MM-dd") + ".txt";
                if (!Directory.Exists(RootLogPath + "\\" + logFolderName))
                    Directory.CreateDirectory(RootLogPath + "\\" + logFolderName);
                if (!File.Exists(LogFilePath))
                {
                    using (FileStream stream = File.Create(LogFilePath))
                    {
                    }
                }

                if (onlyLog == null)
                {
                    onlyLog = new LogWrite();
                    onlyLog.logFolderName = logFolderName;
                }
            }

            return onlyLog;
        }

        /// <summary>
        /// 写日志
        /// </summary>
        /// <param name="message"></param>
        /// <param name="hasDate">是否写入日志记录</param>
        public void Write(string message, bool hasDate = true)
        {
            ThreadPool.QueueUserWorkItem((o) =>
            {
                StringBuilder sb = new StringBuilder(500);
                if (hasDate)
                {
                    //  写入带日期的日志信息
                    sb.Append(DateTime.Now.ToString()).Append(" ");
                    sb.Append(DateTime.Now.Ticks.ToString()).Append("\r\n");
                    sb.Append(message).Append("\r\n");
                    sb.Append("---------------------------------------").Append("\r\n");
                }
                else
                {
                    //  写入普通日志信息
                    sb.Append(message).Append("\r\n");
                }

                lock (LogFilePath)
                {
                    //  此块代码将不会出现“读写文件时文件正由另一进程使用，因此该进程无法访问该文件”问题
                    //  FileShare用于共享文件读写
                    using (FileStream fs = new FileStream(LogFilePath, FileMode.Append, FileAccess.Write, FileShare.Write))
                    {
                        byte[] myByte = System.Text.Encoding.UTF8.GetBytes(sb.ToString());
                        fs.Write(myByte, 0, myByte.Length);
                    }
                }

            });
        }

        /// <summary>
        /// 定期清理日志文件
        /// </summary>
        public void TimingClear()
        {
            //  调用：
            //      LogWrite.ClearSeconds = 60 * 20;
            //      LogWrite.GetInstance("Temp").TimingClear();

            //  清理20分钟之前的Temp文件夹下的日志文件，多个文件夹需要多次调用
            string logFilePath = RootLogPath + "\\" + onlyLog.logFolderName;
            string[] clearFilePaths = Directory.GetFiles(logFilePath);
            foreach (var item in clearFilePaths)
            {
                FileInfo file = new FileInfo(item);
                if ((DateTime.Now - file.LastWriteTime).TotalSeconds > ClearSeconds)
                {
                    File.Delete(item);
                }

            }

        }

    }

}